﻿//Mirco Töpfer

#region Usings

using System;
using System.Collections.Generic;
using pheidippides.common.Classes;
using pheidippides.dataaccess.HelperClasses;
using pheidippides.configuration.Interfaces;
using System.Data;
using pheidippides.logging.Classes;
using pheidippides.dataaccess.DatabaseStrukturEnumns;
using pheidippides.configuration.Classes;
using pheidippides.common.Enums;

#endregion

namespace pheidippides.dataaccess.Classes
{
    public static class TeilnehmerDataAccess
    {
        #region Public Static Methods

        /// <summary>
        /// Gets all.
        /// </summary>
        /// <param name="veranstaltungGuid">The veranstaltung GUID.</param>
        /// <returns></returns>
        public static List<TeilnehmerData> GetAll(Guid veranstaltungGuid)
        {
            Logger.GetInstance().LogMessage(
                "Hole alle Teilnehmer für Veranstaltung " + veranstaltungGuid + " aus der Datenbank", LogLevel.Debug);

            AccessDbSqlHelper dbHelper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            dbHelper.SetProperty(DbEnumTeilnehmer.veranstaltung_fk, veranstaltungGuid);

            DataTable data =
                dbHelper.ExecuteQuery("Select * from " + DbEnumTables.teilnehmer + " where " +
                                      DbEnumTeilnehmer.veranstaltung_fk + " =@" + DbEnumTeilnehmer.veranstaltung_fk);

            return GetTeilnehmerFromDataTable(data);
        }

        /// <summary>
        /// Saves the specified teilnehmer data.
        /// </summary>
        /// <param name="teilnehmerData">The teilnehmer data.</param>
        public static void Save(TeilnehmerData teilnehmerData)
        {
            Logger.GetInstance().LogMessage("Speichere Teilnehmerdata in Datenbank", LogLevel.Debug);

            String sqlCommand;

            if (CheckIfExists(teilnehmerData))
            {
                sqlCommand = "UPDATE " + DbEnumTables.teilnehmer + " SET " +
                             DbEnumTeilnehmer.email + " = @" + DbEnumTeilnehmer.email + ", " +
                             DbEnumTeilnehmer.geburtsdatum + " = @" + DbEnumTeilnehmer.geburtsdatum + ", " +
                             DbEnumTeilnehmer.nachname + " = @" + DbEnumTeilnehmer.nachname + ", " +
                             DbEnumTeilnehmer.Wohnort + " = @" + DbEnumTeilnehmer.Wohnort + ", " +
                             DbEnumTeilnehmer.plz + " = @" + DbEnumTeilnehmer.plz + ", " +
                             DbEnumTeilnehmer.geschlecht + " = @" + DbEnumTeilnehmer.geschlecht + ", " +
                             DbEnumTeilnehmer.startklasse_fk + " = @" + DbEnumTeilnehmer.startklasse_fk + ", " +
                             DbEnumTeilnehmer.straße + " = @" + DbEnumTeilnehmer.straße + "," +
                             DbEnumTeilnehmer.telefon + " = @" + DbEnumTeilnehmer.telefon + ", " +
                             DbEnumTeilnehmer.veranstaltung_fk + " = @" + DbEnumTeilnehmer.veranstaltung_fk + ", " +
                             DbEnumTeilnehmer.verein + " = @" + DbEnumTeilnehmer.verein + ", " +
                             DbEnumTeilnehmer.zeigenotiz + " = @" + DbEnumTeilnehmer.zeigenotiz + ", " +
                             DbEnumTeilnehmer.notiz + " = @" + DbEnumTeilnehmer.notiz + ", " +
                             DbEnumTeilnehmer.startnummer + " = @" + DbEnumTeilnehmer.startnummer + ", " +
                             DbEnumTeilnehmer.vorname + " = @" + DbEnumTeilnehmer.vorname + ", " +
                             DbEnumTeilnehmer.strecke_fk + " = @" + DbEnumTeilnehmer.strecke_fk +
                             //", " +
                             " WHERE " + DbEnumTeilnehmer.id + "= @" + DbEnumTeilnehmer.id;
            }
            else
            {
                sqlCommand = "INSERT INTO " + DbEnumTables.teilnehmer + " (" +
                             DbEnumTeilnehmer.email + ", " +
                             DbEnumTeilnehmer.geburtsdatum + ", " +
                             DbEnumTeilnehmer.id + ", " +
                             DbEnumTeilnehmer.nachname + ", " +
                             DbEnumTeilnehmer.Wohnort + ", " +
                             DbEnumTeilnehmer.plz + ", " +
                             DbEnumTeilnehmer.geschlecht + ", " +
                             DbEnumTeilnehmer.verein + ", " +
                             DbEnumTeilnehmer.startklasse_fk + ", " +
                             DbEnumTeilnehmer.straße + ", " +
                             DbEnumTeilnehmer.telefon + ", " +
                             DbEnumTeilnehmer.zeigenotiz + ", " +
                             DbEnumTeilnehmer.notiz + ", " +
                             DbEnumTeilnehmer.startnummer + ", " +
                             DbEnumTeilnehmer.veranstaltung_fk + ", " +
                             DbEnumTeilnehmer.strecke_fk + ", " +
                             DbEnumTeilnehmer.vorname +
                             //", " +
                             ") VALUES (@" +
                             DbEnumTeilnehmer.email + ", @" +
                             DbEnumTeilnehmer.geburtsdatum + ", @" +
                             DbEnumTeilnehmer.id + ", @" +
                             DbEnumTeilnehmer.nachname + ", @" +
                             DbEnumTeilnehmer.Wohnort + ", @" +
                             DbEnumTeilnehmer.plz + ", @" +
                             DbEnumTeilnehmer.geschlecht + ", @" +
                             DbEnumTeilnehmer.verein + ", @" +
                             DbEnumTeilnehmer.startklasse_fk + ", @" +
                             DbEnumTeilnehmer.straße + ", @" +
                             DbEnumTeilnehmer.telefon + ", @" +
                             DbEnumTeilnehmer.zeigenotiz + ", @" +
                             DbEnumTeilnehmer.notiz + ", @" +
                             DbEnumTeilnehmer.startnummer + ", @" +
                             DbEnumTeilnehmer.veranstaltung_fk + ", @" +
                             DbEnumTeilnehmer.strecke_fk + ", @" +
                             DbEnumTeilnehmer.vorname +
                             //", @" +
                             ")";
            }

            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty(DbEnumTeilnehmer.email.ToString(), teilnehmerData.Emailadresse);
            helper.SetProperty(DbEnumTeilnehmer.geburtsdatum.ToString(), teilnehmerData.Geburtsdatum);
            helper.SetProperty(DbEnumTeilnehmer.geschlecht.ToString(), teilnehmerData.Geschlecht.ToString());
            helper.SetProperty(DbEnumTeilnehmer.id.ToString(), teilnehmerData.Id);
            helper.SetProperty(DbEnumTeilnehmer.nachname.ToString(), teilnehmerData.Nachname);
            helper.SetProperty(DbEnumTeilnehmer.Wohnort.ToString(), teilnehmerData.Wohnort);
            helper.SetProperty(DbEnumTeilnehmer.verein.ToString(), teilnehmerData.Verein);
            helper.SetProperty(DbEnumTeilnehmer.plz.ToString(), teilnehmerData.Plz);
            helper.SetProperty(DbEnumTeilnehmer.zeigenotiz.ToString(), teilnehmerData.ZeigeNotiz.ToString());
            helper.SetProperty(DbEnumTeilnehmer.notiz.ToString(), teilnehmerData.Notiz);
            helper.SetProperty(DbEnumTeilnehmer.startnummer.ToString(), teilnehmerData.Startnummer);
            helper.SetProperty(DbEnumTeilnehmer.startklasse_fk.ToString(), teilnehmerData.StartklasseFk);
            helper.SetProperty(DbEnumTeilnehmer.straße.ToString(), teilnehmerData.Strasse);
            helper.SetProperty(DbEnumTeilnehmer.telefon.ToString(), teilnehmerData.Telefon);
            helper.SetProperty(DbEnumTeilnehmer.veranstaltung_fk.ToString(), teilnehmerData.VeranstaltungFk);
            helper.SetProperty(DbEnumTeilnehmer.vorname.ToString(), teilnehmerData.Vorname);
            helper.SetProperty(DbEnumTeilnehmer.strecke_fk.ToString(), teilnehmerData.StreckeFk);

            helper.ExecuteNonQuery(sqlCommand);
        }

        /// <summary>
        /// Gets the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="veranstaltungGuid">The veranstaltung GUID.</param>
        /// <returns></returns>
        public static TeilnehmerData Get(Guid id, Guid veranstaltungGuid)
        {
            Logger.GetInstance().LogMessage("Hole Teilnehmer " + id + " aus der Datenbank", LogLevel.Debug);
            AccessDbSqlHelper dbHelper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            dbHelper.SetProperty(DbEnumTeilnehmer.id, id);
            dbHelper.SetProperty(DbEnumTeilnehmer.veranstaltung_fk, veranstaltungGuid);

            DataTable data =
                dbHelper.ExecuteQuery("Select * from " + DbEnumTables.teilnehmer + " where " + DbEnumTeilnehmer.id +
                                      " = @" + DbEnumTeilnehmer.id + " and " + DbEnumTeilnehmer.veranstaltung_fk +
                                      " = @" + DbEnumTeilnehmer.veranstaltung_fk);

            if (data.Rows.Count > 1)
                throw new ApplicationException(
                    "Zu dem angefragten Teilnehmer gibt es mehr als ein Objekt in der Datenbank!");

            if (data.Rows.Count == 0)
            {
                Logger.GetInstance().LogMessage(
                    "Es konnte in der Datenbank kein Starter mit der ID " + id + " und der Veranstaltung " +
                    veranstaltungGuid + " gefunden werden!", LogLevel.Warning);
                return null;
            }
            return GetTeilnehmerDataFromRow(data.Rows[0]);
        }

        /// <summary>
        /// Checks if exists.
        /// </summary>
        /// <param name="teilnehmerData">The teilnehmer data.</param>
        /// <returns></returns>
        public static Boolean CheckIfExists(TeilnehmerData teilnehmerData)
        {
            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty(DbEnumTeilnehmer.id, teilnehmerData.Id);
            helper.SetProperty(DbEnumTeilnehmer.veranstaltung_fk, teilnehmerData.VeranstaltungFk);

            DataTable data =
                helper.ExecuteQuery("select count(*) from " + DbEnumTables.teilnehmer + " where " +
                                    DbEnumTeilnehmer.id + " = @" + DbEnumTeilnehmer.id + " and " +
                                    DbEnumTeilnehmer.veranstaltung_fk + " = @" + DbEnumTeilnehmer.veranstaltung_fk);
            
            if (Convert.ToInt32(data.Rows[0][0]) == 1)
                return true;

            if (Convert.ToInt32(data.Rows[0][0]) == 0)
                return false;

            throw new ApplicationException("Es ist mehr als ein erwarteter Teilnehmer in der Datenbank.");
        }

        /// <summary>
        /// Deletes the specified teilnehmer data.
        /// </summary>
        /// <param name="teilnehmerData">The teilnehmer data.</param>
        public static void Delete(TeilnehmerData teilnehmerData)
        {
            Logger.GetInstance().LogMessage("Lösche Teilnehmer " + teilnehmerData.Id + " für Veranstaltung " + teilnehmerData.VeranstaltungFk + " aus der Datenbank", LogLevel.Debug);
            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty(DbEnumTeilnehmer.id, teilnehmerData.Id);
            helper.SetProperty(DbEnumTeilnehmer.veranstaltung_fk, teilnehmerData.VeranstaltungFk);

            helper.ExecuteNonQuery("delete from " + DbEnumTables.teilnehmer + " where " + DbEnumTeilnehmer.id + " = @" +
                                   DbEnumTeilnehmer.id + " and " + DbEnumTeilnehmer.veranstaltung_fk + " = @" +
                                   DbEnumTeilnehmer.veranstaltung_fk);
        }

        #endregion

        #region Private static Methods

        /// <summary>
        /// Gets the teilnehmer from data table.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        private static List<TeilnehmerData> GetTeilnehmerFromDataTable(DataTable data)
        {
            Logger.GetInstance().LogMessage("Erzeuge Teilnehmer aus Dataset", LogLevel.Debug);

            List<TeilnehmerData> teilnehmer = new List<TeilnehmerData>();

            foreach (DataRow row in data.Rows)
            {
                teilnehmer.Add(GetTeilnehmerDataFromRow(row));
            }

            return teilnehmer;
        }

        /// <summary>
        /// Gets the teilnehmer data from row.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <returns></returns>
        private static TeilnehmerData GetTeilnehmerDataFromRow(DataRow row)
        {
            Logger.GetInstance().LogMessage("OR Mapping des Teilnehmers", LogLevel.Debug);

            TeilnehmerData data = new TeilnehmerData();

            data.Emailadresse = row[DbEnumTeilnehmer.email.ToString()].ToString();
            data.Geburtsdatum = Convert.ToDateTime(row[DbEnumTeilnehmer.geburtsdatum.ToString()].ToString());

            foreach (TeilnehmerDataGeschlechtEnum enumValue in Enum.GetValues(typeof (TeilnehmerDataGeschlechtEnum)))
            {
                if (row[DbEnumTeilnehmer.geschlecht.ToString()].ToString().Equals(enumValue.ToString()))
                    data.Geschlecht = enumValue;
            }

            data.Id = new Guid(row[DbEnumTeilnehmer.id.ToString()].ToString());
            data.Nachname = row[DbEnumTeilnehmer.nachname.ToString()].ToString();
            data.Notiz = row[DbEnumTeilnehmer.notiz.ToString()].ToString();
            data.Plz = row[DbEnumTeilnehmer.plz.ToString()].ToString();
            data.Startnummer = row[DbEnumTeilnehmer.startnummer.ToString()].ToString();
            data.Strasse = row[DbEnumTeilnehmer.straße.ToString()].ToString();
            data.Telefon = row[DbEnumTeilnehmer.telefon.ToString()].ToString();
            data.VeranstaltungFk = new Guid(row[DbEnumTeilnehmer.veranstaltung_fk.ToString()].ToString());

            if (row[DbEnumTeilnehmer.startklasse_fk.ToString()].Equals(DBNull.Value))
                data.StartklasseFk = null;
            else
                data.StartklasseFk = new Guid(row[DbEnumTeilnehmer.startklasse_fk.ToString()].ToString());

            if (row[DbEnumTeilnehmer.strecke_fk.ToString()].Equals(DBNull.Value))
                data.StreckeFk = null;
            else
                data.StreckeFk = new Guid(row[DbEnumTeilnehmer.strecke_fk.ToString()].ToString());

            data.Verein = row[DbEnumTeilnehmer.verein.ToString()].ToString();
            data.Vorname = row[DbEnumTeilnehmer.vorname.ToString()].ToString();
            data.Wohnort = row[DbEnumTeilnehmer.Wohnort.ToString()].ToString();
            data.Notiz = row[DbEnumTeilnehmer.notiz.ToString()].ToString();
            data.ZeigeNotiz = Convert.ToBoolean(row[DbEnumTeilnehmer.zeigenotiz.ToString()]);

            return data;
        }

        #endregion
    }
}